<!-- 首页聊天页面 -->
<template>
	<view class="u-flex chat-page"  :class="currentTheme">
		<a-nabbar :name="option.name" />
		<view class="scroll-view" :style="{height:height,width:'100%'}">
			<mescroll-uni :fixed="false" @init="mescrollInit" :down="downOption" @down="downCallback" :up="upOption">
				<view v-for="(item,index) in msgList" :key="index" :id="item.viewId"  v-if="item.contentsType!=='user_authenticate'" >
					<view class="u-text-center u-padding-20 text-order-666 u-font-24" v-if="isShowTime(index)">
						{{item.time | filterTime}}
					</view>
					<view class="msg u-padding-24 u-flex u-col-top"
						:class="[item.from===isMe ? 'u-row-right' : 'u-row-left']"
						v-if="item.contentsType!=='system_tips'">
						<view class="avatar-image-box" v-if="item.from!==isMe&&item.fromUser">
							<item-image :type="'1'" :img="item.fromUser.head" :size="100" />
						</view>
						<view class="msg-content u-margin-20 u-position-relative" :class="[item.contentsType]">
							<text v-if="item.contentsType==='TEXT'">{{item.data}}</text>
							<item-image v-if="item.contentsType==='IMAGE'" :img="item.url" :width="'248'"
								:height="'248'"  :radius="'40'" @click.native="preview(index)" />
							<view class="u-flex" v-if="item.contentsType==='LOCATION'" @click="getThisLocation(item)">
								<u-icon name="weizhi" custom-prefix="custom-icon"
									:color="item.from===isMe ? 'white' : '#765CFE'" size="42"></u-icon>
								<view class="u-margin-left-20 u-flex-1 right-icon">
									<view class="u-font-30 right-text">{{item.ext.name || '无名称'}}</view>
									<view class="u-font-20 u-margin-top-10 right-text"
										:class="[item.from===isMe?'text-color-ccc' : 'text-color-999']">{{item.addr}}
									</view>
								</view>
							</view>
							<text v-if="['VOICE','VIDEO'].includes(item.contentsType)">[暂不支持此类消息]</text>
							<view class="" v-if="['customEvent','CUSTOM'].includes(item.contentsType)&&item.customExts">
								<!-- 邀请评测 -->
								<view>
									{{item.customExts.createName}} 邀请你参加{{item.customExts.name}}的测本，是否立即上车？
								</view>
								<view class="u-flex u-row-right u-margin-top-20"
									v-if="item.from!==isMe&&!item.customExts.isAgree">
									<view class="u-margin-right-20">
										<item-btn :loading="loading" width="110" height="60" @click="agreeOrRefuse(item.customExts,true)">上车</item-btn>
									</view>
									<view>
										<item-btn width="110" type="plain" height="60" @click="agreeOrRefuse(item.customExts,false)">谢绝</item-btn>
									</view>
								</view>
								<view v-if="item.customExts.isAgree"
									class="u-text-right  u-margin-top-20 u-font-20 text-color-C1C1C1">
									{{item.customExts.isAgree}}</view>
							</view>
						</view>
						<view class="avatar-image-box" v-if="item.from===isMe&&item.fromUser">
							<item-image :type="'1'" :img="item.fromUser.head" :size="100" />
						</view>
					</view>
					<view v-else class="system">
						系统消息：<text v-if="item.customExts">{{item.customExts.message}}</text>
					</view>
				</view>
				<view class="" style="height: 100rpx;"></view>
			</mescroll-uni>
		</view>
		<view class="input-box input-fixed-box" :style="{bottom:bottom+'px'}">
			<view
				class="u-flex input-content u-padding-left-48 u-padding-right-24 u-padding-top-16 u-padding-bottom-16">
				<view class="input-box-view u-flex-1" id="input">
					<input v-model="textMsg" :show-confirm-bar="false" :clearable="false" :label-width="0" height="80"
						placeholder="快说点什么吧" class="input" confirm-type="send" :adjust-position="false" confirm-hold
						@confirm="sendText" @focus="keyboardheightchange" @blur="blurChange"></input>
				</view>
				<view class="u-margin-left-40" @click="showChatSet">
					<u-icon name="liaotian-gengduo" size="52" :color="currentThemeObj.primary" custom-prefix="index-custom-icon"></u-icon>
				</view>
			</view>
			<view class="chat-show u-padding-top-30 u-padding-bottom-30" v-if="chatShowFlag">
				<u-row>
					<u-col :span="3" v-for="(item,index) in setList" :key='index'>
						<view class="u-text-center" @click="chooseItem(item.fnName)">
							<view class="icon-box u-flex u-row-center">
								<u-icon :name="`${aliosCdn}/larp/chat-${currentTheme}/${item.icon}.png`" size="60" class="center">
								</u-icon>
							</view>
							<view class="text-order-time u-font-24 u-margin-top-14">{{item.label}}</view>
						</view>
					</u-col>
				</u-row>
			</view>
			<!-- <view class="" :style="{height:safeAreaInsetsBottom+'px',background:'#110E23'}"></view> -->
		</view>
	</view>
</template>

<script>
	import {
		parseTime
	} from '@/utils/index.js'
	import carManager from '@/mixins/carManager.js'
	import MescrollMixin from '@/components/mescroll-uni/mescroll-mixins.js'
	let WebIM = require("@/utils/WebIM")["default"];
	let msgType = require("@/components/chat/msgtype.js");
	let msgStorage = require("@/components/chat/msgstorage");
	let disp = require("@/utils/broadcast");
	import {
		formatTime
	} from '@/utils/index.js'
	import {
		add
	} from '@/api/crud.js'
	export default {
		mixins: [MescrollMixin, carManager],
		data() {
			return {
				downOption: {
					auto: false,
					textColor: "#765CFE" // 下拉刷新的文本颜色
				},
				loading: false,
				upOption: {
					use: false, // 禁止上拉
					toTop: {
						src: '' // 不显示回到顶部按钮
					}
				},
				mTargetType: 'single',
				msgList: [],
				textMsg: '',
				chatShowFlag: false,
				setList: [{
					label: '照片',
					icon: 'image',
					fnName: 'sendImage'
				}, {
					label: '位置',
					icon: 'location',
					fnName: 'location'
				}],
				curChatMsg: '',
				height: 300,
				isFail: false,
				__visibility__: false,
				option: {
					name: '用户名'
				},
				sessionKey: '',
				userList: [],
				isFixedInput: true,
				safeAreaInsetsBottom: 0,
				bottom: 0
			}
		},

		beforeMount() {
			this.__visibility__ = true;
		},
		destroyed() {
			this.__visibility__ = false;
		},
		onUnload() {
			disp.fire("em.chatroom.leave");
		},
		mounted() {
			const me = this;
			WebIM.conn.mr_cache = [];
			this.$nextTick(this.getHeight)
			const option = this.option;
			const sessionKey = option.id + this.isMe;
			this.sessionKey = sessionKey
			const id = option.type == 'groupChat' ? option.id : me.isMe;
			const chatMsg = uni.getStorageSync(sessionKey) || [];
			this.renderMsg(null, null, chatMsg, sessionKey);
			uni.setStorageSync(sessionKey, null);
			disp.on('em.error.sendMsgErr', function(error) {
				me.isFail = true;
			});

			// uni.$on('newChatMsg',({renderableMsg, type, curChatMsg, sesskey})=>{

			// })
			msgStorage.on("newChatMsg", function(renderableMsg, type, curChatMsg, sesskey) {
				me.curChatMsg = curChatMsg;
				if (!me.__visibility__) return; // 判断是否属于当前会话
				if ((renderableMsg.info.from == id || renderableMsg.info.to == id) && sesskey == sessionKey) {
					me.renderMsg(renderableMsg, type, curChatMsg, sessionKey, 'newMsg')
				} else {}
			});
		},
		computed: {
			isMe() {
				return uni.getStorageSync('myUsername')
			}
		},
		methods: {
			async getHeight() {
				try {
					const {
						windowHeight,
						statusBarHeight,
						platform,
						safeAreaInsets
					} = await this.$u.sys();
					this.safeAreaInsetsBottom = safeAreaInsets.bottom;
					const inputBox = await this.$u.getRect('.input-box')
					setTimeout(() => {
						const barHeight = platform == 'ios' ? 44 : 48;
						this.height = windowHeight - statusBarHeight - barHeight - inputBox.height + 'px';
						this.mescroll.scrollTo(99999, 0)
						console.log(this.safeAreaInsetsBottom, inputBox)
						this.isFixedInput = false;
					}, 100)
				} catch (e) {
					//TODO handle the exception
				}
			},
			returnUserItem(id) {
				return this.userList.find(a => a.hxUsername == id) || {}
			},
			downCallback(page) {
				const userid = this.option.id;
				const storageKey = "rendered_" + this.sessionKey;
				let getStorage = uni.getStorageSync(storageKey) || [];
				WebIM.conn.fetchHistoryMessages({
					queue: userid,
					isGroup: this.option.type === 'groupChat',
					success: res => {
						if (Array.isArray(res) && res.length > 0) {
							const list = res.map(this.setUser);
							let topMsg = this.msgList[0];
							this.msgList = [...list, ...this.msgList];
							if (topMsg) {
								let view = uni.createSelectorQuery().select('#' + topMsg.viewId);
								view.boundingClientRect(v => this.mescroll.scrollTo(v.top - 100, 0)).exec();
							} else {
								this.mescroll.scrollTo(99999, 0)
							}
						} else {
							this.mescroll.endSuccess();
							this.mescroll.lockDownScroll(true); // 锁定下拉
						}
					}
				})
				this.mescroll.endSuccess();

			},
			showChatSet() {
				this.chatShowFlag = !this.chatShowFlag;
				setTimeout(this.getHeight, 10)
			},
			//选择图片
			sendImage() {
				uni.chooseImage({
					count: 1,
					sourceType: ["album"],
					success: res => {
						this.upLoadImage(res);
					}
				});
			},
			chooseItem(fnName) {
				this[fnName] && this[fnName]()
			},
			//预览图片
			async preview(index) {
				const item = this.msgList[index];
				const urls = this.msgList.filter(val => val.contentsType === 'IMAGE').map(val => val.url)
				const curr = this.msgList[index].url;
				this.previewUrls(urls, curr)
			},
			//上传图片
			upLoadImage(res) {
				const me = this;
				const tempFilePaths = res.tempFilePaths[0];
				const token = WebIM.conn.context.accessToken;
				uni.getImageInfo({
					src: tempFilePaths,
					success: async res => {
						const allowType = {
							jpg: true,
							gif: true,
							png: true,
							bmp: true,
							jpeg: true
						};
						const width = res.width;
						const height = res.height;
						const filetype = res.type || 'png';
						let str = WebIM.config.appkey.split("#");
						let domain = WebIM.conn.apiUrl + '/'
						if (filetype.toLowerCase() in allowType) {
							uni.uploadFile({
								url: domain + str[0] + "/" + str[1] + "/chatfiles",
								filePath: tempFilePaths,
								name: "file",
								header: {
									"Content-Type": "multipart/form-data",
									Authorization: "Bearer " + token
								},
								success(res) {
									const dataObj = JSON.parse(res.data);
									const id = WebIM.conn.getUniqueId(); // 生成本地消息 id

									const chatmsgtype = msgType.IMAGE
									const msg = new WebIM.message(chatmsgtype, id);
									const body = {
										type: chatmsgtype,
										size: {
											width,
											height
										},
										url: dataObj.uri + "/" + dataObj.entities[0].uuid,
										filetype,
										filename: tempFilePaths
									};
									const {
										id: to,
										chatType
									} = me.option
									msg.set({
										apiUrl: WebIM.config.apiURL,
										body,
										to,
										chatType,
										from: me.isMe,
										roomType: false,
										success: function(argument) {
											disp.fire('em.chat.sendSuccess', id);
										}
									});
									me.saveMessage(msg, chatmsgtype)
								}
							})
						}
					}
				});
			},
			saveSendMsg(evt) {
				msgStorage.saveMsg(evt.msg, evt.type);
			},
			//选择地址
			location() {
				const me = this;
				uni.chooseLocation({
					success: respData => {
						const id = WebIM.conn.getUniqueId();
						const chatmsgtype = msgType.LOCATION
						const msg = new WebIM.message(chatmsgtype, id);
						const {
							id: to,
							chatType
						} = me.option
						msg.set({
							from: me.isMe,
							to,
							roomType: false,
							ext: {
								name: respData.name
							},
							lng: respData.longitude,
							lat: respData.latitude,
							addr: respData.address,
							chatType,
							success(id, serverMsgId) {
								disp.fire('em.chat.sendSuccess', id);
							}
						});
						me.saveMessage(msg, chatmsgtype)
					}
				})
			},
			//保存消息
			saveMessage(msg, type) {
				WebIM.conn.send(msg.body);
				this.saveSendMsg({
					msg,
					type
				});
			},
			//发送文字消息
			sendText() {
				const me = this;
				let id = WebIM.conn.getUniqueId();
				const chatmsgtype = msgType.TEXT;
				let msg = new WebIM.message(chatmsgtype, id);
				const {
					id: to,
					chatType
				} = me.option;
				if (!me.$u.trim(me.textMsg)) {
					me.$u.toast('请输入内容')
					return false;
				}
				msg.set({
					msg: me.textMsg,
					from: me.isMe,
					to,
					roomType: false,
					chatType,
					success(id, serverMsgId) {
						console.log("成功了");
						// 关闭表情弹窗
						disp.fire("em.chat.sendSuccess", id, me.textMsg);
					},
					fail(id, serverMsgId) {
						console.log("失败了");
					},
				});
				try {
					me.saveMessage(msg, chatmsgtype)
				} catch (error) {
					console.log("error", error);
				}
				me.textMsg = "";
				//uni.hideKeyboard();
			},
			//打开当前位置
			getThisLocation(item) {
				uni.openLocation({
					latitude: item.lat,
					longitude: item.lng
				})
			},
			//是否显示时间
			isShowTime(index) {
				if (index === 0) return true;
				const preIndex = index - 1;
				const {
					time: preTime
				} = this.msgList[preIndex];
				const {
					time: currTime
				} = this.msgList[index];
				return currTime - preTime > 1000 * 60 * 5 + 30 //5分钟
			},
			//设置用户头像消息类型等
			setUser(item, index) {
				const userItem = this.returnUserItem(item.from)
				if(item.from==='gbwadmin'){
					item.fromUser = {
						head: '/wx/julie_logo.png'
					}
				}else{
					item.fromUser = {
						head: userItem.avatar || ''
					}
				}
				
				item.contentsType = item.contentsType === "CUSTOM" ? item.customEvent : item.contentsType;
				item.viewId = this.$u.guid(20);
				if (index == -1) return item;
				const storageKey = "rendered_" + this.sessionKey;
				let getStorage = uni.getStorageSync(storageKey) || [];;
				const customExtObj = getStorage.find(val => val.data.customExts && item.customExts && val.data.customExts
					.id === item.customExts.id);
				if (customExtObj && item.customEvent != "system_tips") {
					item.customExts = customExtObj.data.customExts
				}
				return item;
			},
			renderMsg(renderableMsg, type, curChatMsg, sessionKey, isnew) {
				let me = this;
				var historyChatMsgs = uni.getStorageSync("rendered_" + sessionKey) || [];
				historyChatMsgs = historyChatMsgs.concat(curChatMsg);
				if (!historyChatMsgs.length) return;
				if (isnew == 'newMsg') {
					let item = renderableMsg.data;
					if (!item.hasOwnProperty('contentsType')) {
						item.contentsType = me.contentsType(item.type)
						item.data = item.msg;
						item.time = renderableMsg.time;
					}
					item = this.setUser(item, -1)
					me.msgList.push(item)
					me.mescroll.scrollTo(99999, 0)
				}
				uni.setStorageSync("rendered_" + sessionKey, historyChatMsgs);
				let chatMsg = uni.getStorageSync(sessionKey) || [];
				chatMsg.map((item, index) => {
					curChatMsg.map((item2, index2) => {
						if (item2.mid == item.mid) chatMsg.splice(index, 1);
					});
				});
				uni.setStorageSync(sessionKey, chatMsg);
				me.isFail && this.renderFail(sessionKey);
			},
			contentsType(val) {
				return {
					txt: 'TEXT',
					img: 'IMAGE',
					video: 'VIDEO',
					audio: 'AUDIO',
					loc: 'LOCATION'
				} [val]
			},
			renderFail(sessionKey) {
				let me = this;
				let msgList = me.chatMsg;
				msgList.map(item => {
					if (item.mid.substring(item.mid.length - 10) == curMsgMid.substring(curMsgMid.length - 10)) {
						item.msg.data[0].isFail = true;
						item.isFail = true;
						me.setData({
							chatMsg: msgList
						});
					}
				});

				if (me.curChatMsg[0].mid == curMsgMid) {
					me.curChatMsg[0].msg.data[0].isShow = false;
					me.curChatMsg[0].isShow = false;
				}

				uni.setStorageSync("rendered_" + sessionKey, msgList);
				me.isFail = false;
			},
			//同意或拒绝私车邀请
			async agreeOrRefuse(item, flag) {
				const storageKey = "rendered_" + this.sessionKey;
				let getStorage = uni.getStorageSync(storageKey) || [];
				try {
					//同意上车
					if (flag) await this.confirmCarFn(item)
					const txt = flag ? '上车' : '谢绝'
					this.$set(item, 'isAgree', `已${txt}`)
					this.$u.toast(`${txt}成功`);
					if (flag) {
						this.$u.route({
							url: `/pagesA/goOnLarpp/detail`,
							params: {
								id: item.id
							}
						})
					}
					getStorage = getStorage.map(val => {
						if (val.data && val.data.customExts && val.data.customExts.id === item.id) {
							val.data.customExts = item;
						}
						return val;
					})
					uni.setStorageSync(storageKey, getStorage); //设置邀请的状态
				} catch (e) {
					this.$set(item, 'isAgree', e && e.message)
					getStorage = getStorage.map(val => {
						if (val.data && val.data.customExts && val.data.customExts.id === item.id) {
							val.data.customExts = item;
						}
						return val;
					})
					uni.setStorageSync(storageKey, getStorage); //设置邀请的状态
					//uni.setStorageSync("rendered_" + this.sessionKey, this.msgList); //设置邀请的状态
					//TODO handle the exception
				}
			},
			keyboardheightchange(e) {
				this.bottom = e.detail.height;
				this.height = `calc(${this.height} - ${this.bottom}px)`;
				console.log(this.height)
				setTimeout(() => {
					this.mescroll.scrollTo(99999, 0)
				}, 100)
			},
			blurChange() {
				this.bottom = 0;
				this.getHeight();
			}
		},
		async onLoad(option) {
			this.option = option;
			this.option.chatType = option.type;
			let ids = [];
			if (option.type === 'singleChat') {
				ids.push(option.id)
			}
			if (option.type !== 'singleChat') {
				const {
					data
				} = await WebIM.conn.listGroupMember({
					pageNum: 1,
					pageSize: 20,
					groupId: option.id
				})
				ids = data.map(val => val.member || val.owner)
			}
			await add(ids, 'user', 'shopApi', 'findChatDtoByHxUsernames').then(res => {
				this.userList = res;
				const {
					hxUsername,
					avatar,
					nickname
				} = this.loginForm;
				this.userList.push({
					avatar,
					hxUsername,
					nickname
				})
			})
			this.mescroll.triggerDownScroll();
		},
		filters: {
			filterTime: value => {
				return value && formatTime(value) || value
			}
		}
	}
</script>
<style lang="scss">
	page {
		#input .u-input {
			background: transparent;
		}
	}
</style>
<style scoped lang="scss">
	.avatar-image-box {
		width: 100rpx;
		height: 100rpx;
	}

	.input-box {
		// padding-bottom: constant(safe-area-inset-bottom);  
		// padding-bottom: env(safe-area-inset-bottom);
		// padding-bottom: var(--window-bottom);
		background: white;
		padding-bottom: 20px;
		width: 100%;
	}

	.input-content {
		border-top: 1rpx solid transparentize($color: #fff, $amount: 0.8);
		border-bottom: 1rpx solid transparentize($color: #fff, $amount: 0.8);
	}

	.input-box-view {
		background: var(--background-second-color);
		border-radius: 50px;
		box-sizing: border-box;
		padding: 0 20rpx;
		font-size: 24rpx;
	}

	.icon-box {
		width: 128rpx;
		height: 128rpx;
		background:var(--background-second-color);
		border-radius: 28rpx;
		margin: 0 auto;
	}

	.msg {
		.msg-content {

			&.TEXT,
			&.LOCATION,
			&.VOICE,
			&.VIDEO,
			&.CUSTOM,
			&.customEvent {
				padding: 23rpx 36rpx;
				border-radius: 38rpx;
				font-size: 32rpx;
				max-width: 474rpx;
				word-break: break-all;
				box-sizing: border-box;
				text-align: justify;

				&::after {
					content: "";
					position: absolute;
					border-top: 35rpx solid;
					border-left: 20rpx solid transparent;
					border-right: 35rpx solid transparent;
					border-radius: 3px;
				}
			}
		}

		&.u-row-right {
			.msg-content {
				&::after {
					border-top-color: #765CFE;
					right: -8rpx;
					top: 0;
				}

				&.TEXT,
				&.LOCATION,
				&.VOICE,
				&.VIDEO,
				&.CUSTOM,
				&.customEvent {
					background: #765CFE;
					color: white;
				}
			}
		}

		&.u-row-left {
			.msg-content {
				&::after {
					left: -8rpx;
					top: 0;
					border-top-color: white;
				}

				&.TEXT,
				&.LOCATION,
				&.VOICE,
				&.VIDEO,
				&.CUSTOM,
				&.customEvent {
					background: white;
				}
			}
		}
	}

	.chat-page {
		flex-direction: column;
		max-height: 100vh;
	}

	.scroll-view {
		flex-shrink: 0;
		flex: 1;
	}

	.right-icon {
		flex-shrink: 0;
		flex: 1;
		width: 280rpx;

		.right-text {
			white-space: nowrap;
			overflow: hidden;
			text-overflow: ellipsis;
		}
	}

	.system {
		text-align: center;
		max-width: 50vw;
		box-sizing: border-box;
		padding: 10rpx;
		background-color: transparentize($color: #000000, $amount: 0.6);
		color: rgba(255, 255, 255, 0.5);
		font-size: 24rpx;
		margin: 0 auto 10rpx;
		border-radius: 30rpx;
	}

	.input-fixed-box {
		position: absolute;
		bottom: 0;
		left: 0;
		right: 0;

	}

	.input {
		height: 80rpx;
	}
</style>
